﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Chefbook.DataAccess;
using Chefbook.ViewModels;
using Chefbook.DataObjects;
using Chefbook.HelperMethods;
using UnitTests.Properties;

namespace UnitTests.DataAccess
{
    [TestFixture]
    public class ChefbookXmlRepositoryFixture
    {
        ChefbookXmlRepository repo;
        private List<Category> roots;

        [SetUp]
        public void Init()
        {
            repo = new ChefbookXmlRepository(Resources.RecipeXmlPath, Resources.CategoryXmlPath);

            roots = new List<Category>();

            Category tasties = new Category(null) { Name = "Tasties" };
            Category pasta = new Category(tasties) { Name = "Pasta" };
            Category chicken = new Category(pasta) { Name = "Chicken" };
            
            Recipe chickenShrimpScampi = new Recipe(chicken)
            {
                Name = "Chicken and Shrimp Scampi",
                Description="A delicious combination of shrimp and chicken",
                Directions="Take some chicken, and shrimp and cut them up and cook",
                CookTime= TimeSpan.FromMinutes(30),
                PrepTime = TimeSpan.FromMinutes(45),
            };
            chickenShrimpScampi.AddIngredient(new Ingredient() { Name = "Chicken breasts, sliced", Amount = 1, Units = "Lbs" });
            chickenShrimpScampi.AddIngredient(new Ingredient() { Name = "Jumbo Shrimp", Amount = 10, Units = "" });
            chickenShrimpScampi.AddIngredient(new Ingredient() { Name = "Salted Butter", Amount = 3, Units = "tbsp" });
            
            Recipe chickenFettuciniAlfredo = new Recipe(chicken)
            {
                Name = "Chicken Fettuccini Alfredo",
                Description = "A creamy chicken alfredo",
                Directions = "Boil up the pasta",
                CookTime= TimeSpan.FromMinutes(75),
                PrepTime = TimeSpan.FromMinutes(25),
            };
            chickenFettuciniAlfredo.AddIngredient(new Ingredient() { Name = "Chicken breasts, sliced", Amount = 1, Units = "Lbs" });
            chickenFettuciniAlfredo.AddIngredient(new Ingredient() { Name = "Fettuccini", Amount = 1, Units = "Box" });
            chickenFettuciniAlfredo.AddIngredient(new Ingredient() { Name = "Alfredo Sauce", Amount = 2, Units = "Jars" });

            Category beef = new Category(pasta) { Name = "Beef" };
            Recipe spaghettiAndMeatballs = new Recipe(beef)
            {
                Name = "Spaghetti and Meatballs",
                Description = "Plain old spaghetti and meatballs",
                Directions = "Boil up the pasta and ball up the meat",
                CookTime = TimeSpan.FromMinutes(23),
                PrepTime = TimeSpan.FromMinutes(12),
            };
            spaghettiAndMeatballs.AddIngredient(new Ingredient() { Name = "Ground Beef", Amount = 1, Units = "Lbs" });
            spaghettiAndMeatballs.AddIngredient(new Ingredient() { Name = "Spaghetti", Amount = 1, Units = "Box" });
            spaghettiAndMeatballs.AddIngredient(new Ingredient() { Name = "Spaghetti Sauce", Amount = 2, Units = "Jars" });

            Recipe lasagna = new Recipe(beef) { Name = "Lasagna" };
            Category pork = new Category(pasta) { Name = "Pork" };
            pork.AddRecipe(lasagna);
            Category seafood = new Category(pasta) { Name = "Seafood" };
            seafood.AddRecipe(chickenShrimpScampi);

            roots.Add(tasties);
        }

        [Test]
        public void RootCategoriesPopulatedTest()
        {
            var expected = new List<CategoryViewModel>();
            foreach (var item in roots)
            {
                expected.Add(new CategoryViewModel(item, repo));   
            }
            var actual = repo.RootCategories;
            Assert.AreEqual(expected.Count, actual.Count);
            foreach (var item in expected.Zip(actual, (a, b) => new { First = a, Second = b }))
            {
                Assert.True(item.First.ValueEquals(item.Second));
            }
            
        }

    }
}
